home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Tools & Goodies / More View Resources / Radio Groups / FormView.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  25.4 KB  |  738 lines  |  [TEXT/CWIE]

  1. //========================================================================================
  2. //
  3. //    File:                FormView.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Author:                Laurent Delamare
  7. //
  8. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "Form.hpp"
  13.  
  14. #ifndef FORMVIEW_H
  15. #include "FormView.h"
  16. #endif
  17.  
  18. #ifndef PART_H
  19. #include "Part.h"
  20. #endif
  21.  
  22. #ifndef FRAME_H
  23. #include "Frame.h"
  24. #endif
  25.  
  26. #ifndef SCROLLED_H
  27. #include "ScrollEd.h"
  28. #endif
  29.  
  30. #ifndef RADIOGRP_H
  31. #include "RadioGrp.h"
  32. #endif
  33.  
  34. // ----- Framework Layer -----
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. #ifndef FWFRAME_H
  41. #include "FWFrame.h"
  42. #endif
  43.  
  44. #ifndef FWLISTBX_H
  45. #include "FWListBx.h"
  46. #endif
  47.  
  48. #ifndef FWBUTTON_H
  49. #include "FWButton.h"
  50. #endif
  51.  
  52. #ifndef FWEDVIEW_H
  53. #include "FWEdView.h"
  54. #endif
  55.  
  56. #ifndef FWPOPUP_H
  57. #include "FWPopup.h"
  58. #endif
  59.  
  60. #ifndef FWCLUSTR_H
  61. #include "FWClustr.h"
  62. #endif
  63.  
  64. #ifndef FWCONTXT_H
  65. #include "FWContxt.h"
  66. #endif
  67.  
  68. #ifndef FWSCLBAR_H
  69. #include "FWSclBar.h"
  70. #endif
  71.  
  72. #ifndef FWSTATIC_H
  73. #include "FWStatic.h"
  74. #endif
  75.  
  76. // ----- OS Layer -----
  77.  
  78. #ifndef FWMENU_H
  79. #include "FWMenu.h"
  80. #endif
  81.  
  82. #ifndef FWEVENT_H
  83. #include "FWEvent.h"
  84. #endif
  85.  
  86. #ifndef FWRECT_H
  87. #include "FWRect.h"
  88. #endif
  89.  
  90. #ifndef FWRECSHP_H
  91. #include "FWRecShp.h"
  92. #endif
  93.  
  94. #ifndef FWTXTSHP_H
  95. #include "FWTxtShp.h"
  96. #endif
  97.  
  98. #ifndef FWPICSHP_H
  99. #include "FWPicShp.h"        
  100. #endif
  101.  
  102. #ifndef FWALERT_H
  103. #include "FWAlert.h"            
  104. #endif
  105.  
  106. // ----- OpenDoc Includes -----
  107.  
  108. #ifndef SOM_Module_OpenDoc_Commands_defined
  109. #include <CmdDefs.xh>
  110. #endif
  111.  
  112. #ifndef SOM_Module_OpenDoc_StdProps_defined
  113. #include <StdProps.xh>
  114. #endif
  115.  
  116. #ifndef SOM_ODSession_xh
  117. #include <ODSessn.xh>
  118. #endif
  119.  
  120. #ifndef SOM_ODDispatcher_xh
  121. #include <Disptch.xh>
  122. #endif
  123.  
  124. //========================================================================================
  125. // RunTime Info
  126. //========================================================================================
  127.  
  128. #ifdef FW_BUILD_MAC
  129. #pragma segment odfform
  130. #endif
  131.  
  132. FW_DEFINE_CLASS_M1(CFormView, FW_CSuperView)
  133.  
  134. const FW_ClassTypeConstant LFormView = FW_TYPE_CONSTANT('F','r','m','v');
  135. FW_REGISTER_ARCHIVABLE_CLASS(LFormView, CFormView, CFormView::Create, FW_CView::Read, CFormView::Destroy, FW_CView::Write)
  136.  
  137. //========================================================================================
  138. // CFormView
  139. //========================================================================================
  140. // Implementation of a content view drawing a background picture
  141.  
  142. //----------------------------------------------------------------------------------------
  143. // CFormView::CFormView
  144. //----------------------------------------------------------------------------------------
  145.  
  146. CFormView::CFormView(Environment* ev, 
  147.                         FW_CSuperView* container,
  148.                         const FW_CRect& contentRect,
  149.                         const FW_CPoint& extent) :
  150.     FW_CSuperView(ev, container, contentRect, kFormViewID, extent, FW_kXYScrolling),
  151.     fFirstFormOn(true)
  152. {    
  153.     fRadioClusters[kModemSpeedCluster] = NULL;    
  154.     fRadioClusters[kDiscoverODFCluster] = NULL;    
  155.     fRadioClusters[kUsingOpenDocCluster] = NULL;    
  156.     
  157.     // Adjust the bounds but don't redraw now 
  158.     CenterInFrame(ev, contentRect.Size(), FALSE);
  159. }
  160.  
  161. //----------------------------------------------------------------------------------------
  162. // CFormView::CFormView
  163. //----------------------------------------------------------------------------------------
  164.  
  165. CFormView::CFormView(Environment* ev) :
  166.     FW_CSuperView(ev),
  167.     fFirstFormOn(true)
  168. {    
  169.     fRadioClusters[kModemSpeedCluster] = NULL;    
  170.     fRadioClusters[kDiscoverODFCluster] = NULL;    
  171.     fRadioClusters[kUsingOpenDocCluster] = NULL;    
  172.  
  173.     // Adjust the bounds but don't redraw now 
  174. //     CenterInFrame(ev, contentRect.Size(), FALSE);  can do that here?
  175. }
  176.  
  177. //----------------------------------------------------------------------------------------
  178. // CFormView::~CFormView
  179. //----------------------------------------------------------------------------------------
  180.  
  181. CFormView::~CFormView()
  182. {
  183.     // fRadioClusters are deleted when their last radio button is deleted
  184. }
  185.  
  186.  
  187. //----------------------------------------------------------------------------------------
  188. // CFormView::ActivateTarget
  189. //----------------------------------------------------------------------------------------
  190. // ActivateTarget is called the first time the frame gets the selection focus (because
  191. // a content view is always the frame's default target). We use this to change the target 
  192. // to be the first text-edit field, i.e. to activate this field for keyboard events.
  193.  
  194. void CFormView::ActivateTarget(Environment* ev, FW_Boolean tabSelection)
  195. {
  196.     FW_CView* edview = FindViewById(ev, kFirstNameEdViewID);
  197.     
  198.     // Be sure that the edit view wants to be the target before doing it
  199.     // (otherwise it would be activated even when it's invisible in the 2nd form)
  200.      
  201.     if (edview->WantsToBeTarget(ev))
  202.         edview->BecomeTarget(ev, tabSelection);
  203. }
  204.  
  205. //----------------------------------------------------------------------------------------
  206. //    CFormView::PostCreateViewFromStream
  207. //----------------------------------------------------------------------------------------
  208. // PostCreateViewFromStream is called after subviews are created from resources.  
  209. // Implement initializations for this view that can't be done from a stream.
  210.  
  211. void CFormView::PostCreateViewFromStream(Environment* ev)
  212. {
  213.     // ----- Link the frame to the list-box in order to respond to double-clicks
  214.     //        (standard controls are linked by defining their "receiver" resource field)
  215.     
  216.     // Note: this code could also reside in CFormFrame::PostCreateViewFromStream
  217.     //         if you prefer to do all PostCreate initializations in one place.
  218.     
  219.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  220.     FW_CListBox* listbox = (FW_CListBox*)FindViewById(ev, kPlatformListBoxID);
  221.     
  222.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  223.     
  224.     // ----- Add a behavior to the list-box to handle mouse clicks
  225.     //        (easier than subclassing FW_CListBox and defining a new resource type)
  226.     
  227.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  228.     listbox->AdoptEventHandler(ev, behavior);
  229.     
  230.     // ----- Disable the "Remove" button by default
  231.     FW_CButton* rmButton = (FW_CButton*) FindViewById(ev, kRemoveButtonID);
  232.     rmButton->Disable(ev);
  233. }
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // CFormView::CreateOwnSubViews
  237. //----------------------------------------------------------------------------------------
  238. // Called from CFormFrame::CreateSubViews if compiled without using view resources
  239.  
  240. void CFormView::CreateOwnSubViews(Environment* ev)
  241. {
  242.     // NOTE: we left this code commented out because of compiling problem in Release mode
  243.     //        with CodeWarrior 8.  Unless you have 60MB or so you'll get an "Out of memory"
  244.     //        error!  It must be caused by the full-optimization flags used in Release mode.
  245. #if 0
  246.     FW_Fixed fixed20     = FW_IntToFixed(20);
  247.     FW_Fixed fixed40     = FW_IntToFixed(40);
  248.     FW_CFont timesBold(FW_kTimes, FW_kBold, FW_IntToFixed(12));
  249.     FW_CFont helvetica(FW_kHelvetica, FW_kPlain, FW_IntToFixed(12));
  250.  
  251.     FW_CRect viewRect;        // working rect for creating the views
  252.  
  253.     // ----- Create edit fields in the content view
  254.     viewRect.Set(FW_IntToFixed(290), FW_IntToFixed(90), FW_IntToFixed(450), FW_IntToFixed(107));
  255.     FW_CPoint offset(FW_kFixed0, fixed20);
  256.     for (int i = 0; i < 4; i++) {
  257.         FW_CEditView* editView = FW_NEW(FW_CEditView, (ev, this, kFirstNameEdViewID+i, viewRect));
  258.         editView->SetFont(ev, timesBold);
  259.         viewRect += offset;
  260.     }
  261.     
  262.     // ----- Create custom scrolling edit view with its scrollbar
  263.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(200), FW_IntToFixed(450), FW_IntToFixed(290));    
  264.     FW_CRect vertSbRect(viewRect.right - FW_kFixedPos1, viewRect.top, 
  265.                         viewRect.right + FW_IntToFixed(15), viewRect.bottom);
  266.     FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, kEditVScrollBarID, vertSbRect));
  267.     vertSB->SetBindings(ev, FW_kFixedBounds);
  268.     CScrollEdit* scrollEdit = FW_NEW(CScrollEdit, (ev, this, kFirstNameEdViewID+4, viewRect, NULL, vertSB, FW_CString()));
  269.  
  270.     // ----- Create the "Subscribe" check box 
  271.     //         Use null message (no receiver) and initial value of 1 to turn it on
  272.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(310), FW_IntToFixed(200), FW_IntToFixed(324));
  273.     FW_CButton* check = FW_NEW(FW_CButton, (ev, this, kSubscribeCheckID, viewRect, FW_kCheckButton, 
  274.                                 FW_CString("Subscribe to ODFFlash"), timesBold, 0, 1));
  275.  
  276.     // ----- Create the Modem Speed radio butttons, their group box & the radio cluster
  277.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(360), FW_IntToFixed(220), FW_IntToFixed(440));
  278.     FW_CGroupBox* modemSpeed = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  279.                                                 FW_CString(" Modem speed used"), timesBold));
  280.  
  281.     viewRect.Set(fixed40, FW_IntToFixed(380), FW_IntToFixed(210), FW_IntToFixed(396));
  282.     FW_CButton* radio1 = FW_NEW(FW_CButton, (ev, this, k14400RadioID, viewRect, 
  283.                                         FW_kRadioButton, FW_CString("14.4 Kbps or lower")));
  284.     viewRect.Offset(FW_kFixed0, fixed20);
  285.     FW_CButton* radio2 = FW_NEW(FW_CButton, (ev, this, k28800RadioID, viewRect, 
  286.                                         FW_kRadioButton, FW_CString("28.8 Kbps to 256 Kbps")));
  287.     viewRect.Offset(FW_kFixed0, fixed20);
  288.     FW_CButton* radio3 = FW_NEW(FW_CButton, (ev, this, kFasterRadioID, viewRect, 
  289.                                         FW_kRadioButton, FW_CString("Faster than 256 Kbps")));
  290.  
  291.     fRadioClusters[kModemSpeedCluster] = FW_NEW(FW_CRadioCluster, (ev));
  292.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio2);
  293.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio1);
  294.     fRadioClusters[kModemSpeedCluster]->AddRadio(ev, radio3);
  295.     
  296.     // ----- Create a list box (helvetica font, multiple selections, answer to double-clicks)
  297.     viewRect.Set(FW_IntToFixed(250), FW_IntToFixed(362), FW_IntToFixed(400), FW_IntToFixed(440));
  298.     FW_CListBox* listbox = FW_NEW(FW_CListBox, (ev, this, viewRect, kPlatformListBoxID, 10, 
  299.                                     true, helvetica, FW_kListBoxDoubleClickedMsg, false));
  300.     listbox->SetDrawingMode(ev, FALSE);
  301.     listbox->SetStringItem(ev, 1, FW_CString("Mac OS"));
  302.     listbox->SetStringItem(ev, 2, FW_CString("OS/2 Warp"));
  303.     listbox->SetStringItem(ev, 3, FW_CString("Windows 95"));
  304.     listbox->SetStringItem(ev, 4, FW_CString("Windows NT"));
  305.     listbox->SetStringItem(ev, 5, FW_CString("IBM AIX"));
  306.     listbox->SetStringItem(ev, 6, FW_CString("Sun Sparc Solaris"));
  307.     listbox->SetStringItem(ev, 7, FW_CString("Sun OS 4.1.x"));
  308.     listbox->SetStringItem(ev, 8, FW_CString("HP /UX"));
  309.     listbox->SetStringItem(ev, 9, FW_CString("Unix IRIX"));
  310.     listbox->SetStringItem(ev, 10, FW_CString("Unix Linux"));
  311.     listbox->SetDrawingMode(ev, TRUE);
  312.     
  313.     // ----- Create the Add/Remove buttons
  314.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(370), FW_IntToFixed(480), FW_IntToFixed(390));
  315.     FW_CButton* addButton = FW_NEW(FW_CButton, (ev, this, kAddButtonID, viewRect, 
  316.                                         FW_kPushButton, FW_CString("Add")));
  317.     viewRect.Set(FW_IntToFixed(410), FW_IntToFixed(400), FW_IntToFixed(480), FW_IntToFixed(420));
  318.     FW_CButton* removeButton = FW_NEW(FW_CButton, (ev, this, kRemoveButtonID, viewRect, 
  319.                                         FW_kPushButton, FW_CString("Remove")));
  320.     removeButton->Disable(ev);
  321.     
  322.     // ----- Create the "browsing time" popup
  323.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(477), FW_IntToFixed(230), FW_IntToFixed(497));
  324.     FW_CPopupMenu* popup1 = FW_NEW(FW_CPopupMenu, (ev, this, kBrowseTimePopupID, viewRect, 
  325.                                         kBrowseTimeMenuResID, FW_CString()));
  326.  
  327.     // ----- Create the "online time" popup
  328.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(540), FW_IntToFixed(230), FW_IntToFixed(560));
  329.     FW_CPopupMenu* popup2 = FW_NEW(FW_CPopupMenu, (ev, this, kOnlineTimePopupID, viewRect, 
  330.                                         kOnlineTimeMenuResID, FW_CString()));
  331.  
  332.     // ----- Create the "First Discover" radio butttons & their radio cluster
  333.     viewRect.Set(FW_IntToFixed(30), FW_IntToFixed(580), FW_IntToFixed(350), FW_IntToFixed(700));
  334.     FW_CGroupBox* discoverGroupB = FW_NEW(FW_CGroupBox, (ev, this, viewRect, 
  335.                                         FW_CString(" How did you discover ODFWired?"), timesBold));
  336.  
  337.     viewRect.Set(fixed40, FW_IntToFixed(600), FW_IntToFixed(300), FW_IntToFixed(616));
  338.     FW_CButton* radio4 = FW_NEW(FW_CButton, (ev, this, kWorldMouthRadioID, viewRect, 
  339.                                         FW_kRadioButton, FW_CString("Word of mouth")));
  340.     viewRect.Offset(FW_kFixed0, fixed20);
  341.     FW_CButton* radio5 = FW_NEW(FW_CButton, (ev, this, kHyperLinkRadioID, viewRect, 
  342.                                         FW_kRadioButton, FW_CString("Hyperlink from another site:")));
  343.     viewRect.Offset(FW_kFixed0, fixed20);
  344.     FW_CButton* radio6 = FW_NEW(FW_CButton, (ev, this, kMacTechRadioID, viewRect, 
  345.                                         FW_kRadioButton, FW_CString("Ad in MacTech Magazine")));
  346.     viewRect.Offset(FW_kFixed0, fixed20);
  347.     FW_CButton* radio7 = FW_NEW(FW_CButton, (ev, this, kMagazineRadioID, viewRect, 
  348.                                         FW_kRadioButton, FW_CString("Other magazine, newspaper, radio")));
  349.     viewRect.Offset(FW_kFixed0, fixed20);
  350.     FW_CButton* radio8 = FW_NEW(FW_CButton, (ev, this, kOtherRadioID, viewRect, 
  351.                                         FW_kRadioButton, FW_CString("Other")));
  352.     fRadioClusters[kDiscoverODFCluster] = FW_NEW(FW_CRadioCluster, (ev));
  353.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio4);
  354.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio5);
  355.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio6);
  356.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio7);
  357.     fRadioClusters[kDiscoverODFCluster]->AddRadio(ev, radio8);
  358.     
  359.     // ----- Create the "using OpenDoc" radio butttons & their radio cluster
  360.     viewRect.Set(fixed40, FW_IntToFixed(725), FW_IntToFixed(100), FW_IntToFixed(740));
  361.     FW_CButton* radio9 = FW_NEW(FW_CButton, (ev, this, kYesRadioID, viewRect, 
  362.                                         FW_kRadioButton, FW_CString("Yes")));
  363.     viewRect.Offset(FW_kFixed0, fixed20);
  364.     FW_CButton* radio10 = FW_NEW(FW_CButton, (ev, this, kNoRadioID, viewRect, 
  365.                                         FW_kRadioButton, FW_CString("No")));
  366.     fRadioClusters[kUsingOpenDocCluster] = FW_NEW(FW_CRadioCluster, (ev));
  367.     fRadioClusters[kUsingOpenDocCluster]->AddRadio(ev, radio9);
  368.     fRadioClusters[kUsingOpenDocCluster]->AddRadio(ev, radio10);
  369.  
  370.     // ----- Create the "Subscribe" button at the bottom of the content view
  371.     FW_CString label("Join ODFWired!");
  372.     viewRect.Set(FW_IntToFixed(300), FW_IntToFixed(750), FW_IntToFixed(450), FW_IntToFixed(775));
  373.     FW_CButton* pushButton = FW_NEW(FW_CButton, (ev, this, kSubscribeButtonID, viewRect, 
  374.                                         FW_kPushButton, label));
  375.  
  376.     // ----- Link the frame to the controls it wants to respond to
  377.     //        (CFormFrame was defined as an FW_MReceiver and thus can respond to
  378.     //        notitications.  We could also have decided to make CFormView the
  379.     //        receiver, it's a matter of choice)
  380.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  381.     
  382.     pushButton->LinkControlTo(ev, frame);
  383.     addButton->LinkControlTo(ev, frame);
  384.     removeButton->LinkControlTo(ev, frame);
  385.     radio10->LinkControlTo(ev, frame);
  386.     popup1->LinkControlTo(ev, frame);
  387.     
  388.     frame->AddNotifier(listbox, FW_kListBoxDoubleClickedMsg);
  389.  
  390.     // ----- Add a behavior to the list-box to handle mouse clicks
  391.     //        (easier than subclassing FW_CListBox and defining a new resource type)    
  392.     CMouseUpBehavior* behavior = FW_NEW(CMouseUpBehavior, (ev, listbox));
  393.     listbox->AdoptEventHandler(ev, behavior);
  394. #endif
  395. }
  396.  
  397. //----------------------------------------------------------------------------------------
  398. // CFormView::Draw
  399. //----------------------------------------------------------------------------------------
  400.  
  401. void CFormView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  402. {
  403.     // Set up drawing context for this view
  404.     FW_CViewContext vc(ev, this, odFacet, invalidShape);
  405.  
  406.     // Erase with white first 
  407.     FW_CRect invalidRect;
  408.     vc.GetClipRect(invalidRect);
  409.     FW_CRectShape::RenderRect(vc, invalidRect, FW_kFill, FW_kWhiteEraseInk);
  410.  
  411.     CFormFrame* frame = (CFormFrame*)GetFrame(ev);
  412.     
  413.     if (fFirstFormOn)
  414.     {
  415.         // Draw a background picture (which was loaded in CFormPrt::InitPicture)
  416.         // Note: this picture contains static text that could have been drawn using
  417.         //         Static Text view resources, as it was done in the 2nd form.
  418.         frame->GetFormPart()->GetPictShape1()->Render(vc);
  419.     }
  420.     else 
  421.     {
  422.         // Draw a background picture & the data entered by the user
  423.         frame->GetFormPart()->GetPictShape2()->Render(vc);
  424.         DrawUserData(ev, vc);
  425.     }
  426.     
  427.     // SubViews of CFormView are drawn recursively after this point.
  428.     
  429.     // Mac Note: If you want to draw Controls with a non-white background color to match
  430.     // the color of their parent view, you need either to define a color table for
  431.     // the window (see CPwdDialogFrame::FacetAdded for an example) or define color tables
  432.     // for individual controls.  See "Inside Macintosh: Macintosh Toolbox Essentials".
  433. }
  434.  
  435. //----------------------------------------------------------------------------------------
  436. // CFormView::CenterInFrame
  437. //----------------------------------------------------------------------------------------
  438.  
  439. void CFormView::CenterInFrame(Environment* ev, FW_CPoint& contentSize, FW_Boolean redraw)
  440. {
  441.     FW_CPoint    viewSize(GetSize(ev));
  442.     FW_CPoint    viewExtent(GetExtent(ev));
  443.     FW_CPoint    viewLoc;
  444.  
  445.     FW_CRect contentRect(FW_kZeroPoint, contentSize);
  446.     if (GetFrame(ev)->IsRoot(ev) == FALSE)
  447.     {
  448.         contentRect.Inset(FW_kFixedPos1);
  449.         contentSize = contentRect.Size();
  450.     }
  451.         
  452.     // Center the content view if it's smaller, or align it if it's bigger
  453.     if (contentSize.x > viewExtent.x) 
  454.     {
  455.         viewLoc.x = contentRect.left + FW_Half(contentSize.x - viewExtent.x);
  456.         viewSize.x = viewExtent.x;
  457.     }
  458.     else 
  459.     { 
  460.         viewLoc.x = contentRect.left;
  461.         viewSize.x = contentSize.x;
  462.     }
  463.     
  464.     if (contentSize.y > viewExtent.y) 
  465.     {
  466.         viewLoc.y = contentRect.top + FW_Half(contentSize.y - viewExtent.y);
  467.         viewSize.y = viewExtent.y;
  468.     }
  469.     else 
  470.     {
  471.         viewLoc.y = contentRect.top;
  472.         viewSize.y = contentSize.y;
  473.     }
  474.     
  475.     SetLocation(ev, viewLoc, redraw);
  476.     SetSize(ev, viewSize, redraw);
  477. }
  478.  
  479.  
  480. //----------------------------------------------------------------------------------------
  481. // CFormView::AdjustToNewLayout
  482. //----------------------------------------------------------------------------------------
  483.  
  484. void CFormView::AdjustToNewLayout(Environment *ev, const FW_CPoint& oldExtent, 
  485.                                     const FW_CPoint& newExtent, FW_Boolean redraw)    
  486. {
  487. FW_UNUSED(oldExtent);
  488.  
  489.     // Adjust the new frame size to remove scroll-bar space
  490.     FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  491.     FW_CPoint size = newExtent;
  492.     size.x -= sbSize.x;
  493.     size.y -= sbSize.y;
  494.     
  495.     CenterInFrame(ev, size, redraw);
  496.     
  497.     return;
  498. }
  499.  
  500. //----------------------------------------------------------------------------------------
  501. // CFormView::DoMouseDown
  502. //----------------------------------------------------------------------------------------
  503.  
  504. FW_Boolean CFormView::DoMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  505. {
  506.     // Go back to the first form when clicking on the 2nd one
  507.     if (!fFirstFormOn)
  508.         SwitchForm(ev);
  509.  
  510.     return TRUE;
  511. }
  512.  
  513. //----------------------------------------------------------------------------------------
  514. // CFormView::SwitchForm
  515. //----------------------------------------------------------------------------------------
  516.  
  517. void     CFormView::SwitchForm(Environment* ev)
  518. {
  519.     if (fFirstFormOn)
  520.     {
  521.         fFirstFormOn = FALSE;
  522.         
  523.         // Hide all subviews but don't hide the form view itself
  524.         SetVisible(ev, FALSE, TRUE);
  525.         SetVisible(ev, TRUE, FALSE);
  526.     }
  527.     else
  528.     {
  529.         fFirstFormOn = TRUE;
  530.         
  531.         // Show all subviews
  532.         SetVisible(ev, TRUE, TRUE);
  533.         
  534.     }
  535.     
  536.     // Force a redraw
  537.     Invalidate(ev);
  538. }
  539.  
  540. //----------------------------------------------------------------------------------------
  541. // CFormView::DrawUserData
  542. //----------------------------------------------------------------------------------------
  543.  
  544. void CFormView::DrawUserData(Environment *ev, FW_CViewContext& vc)
  545. {
  546.     FW_CPoint        position;
  547.     FW_Fixed         vDelta = FW_IntToFixed(24);
  548.     int                i;
  549.     
  550.     FW_CString        str;
  551.     FW_CString32    yesStr("Yes");
  552.     FW_CString32    noStr("No");
  553.     
  554.     position.x = FW_IntToFixed(200);
  555.     position.y = FW_IntToFixed(90);
  556.  
  557.     // Edit views
  558.     FW_CEditView*    edview;
  559.     for (i = 0; i < 4; i++)
  560.     {
  561.         edview = (FW_CEditView*)FindViewById(ev, kFirstNameEdViewID+i);
  562.         str = edview->GetText(ev);
  563.         FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  564.         position.y += vDelta;
  565.     }
  566.     
  567.     // Check box
  568.     FW_CButton*        button;
  569.     button = (FW_CButton*)FindViewById(ev, kSubscribeCheckID);
  570.     FW_CTextShape::RenderText(vc, button->GetState(ev) ? yesStr : noStr, position, FW_kNormalFont);
  571.     position.y += vDelta;
  572.     
  573.     // Popups
  574.     FW_CPopupMenu* popup1 = (FW_CPopupMenu*) FindViewById(ev, kBrowseTimePopupID);
  575.     popup1->GetMenuString(ev, str);
  576.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  577.     position.y += vDelta;
  578.  
  579.     FW_CPopupMenu* popup2 = (FW_CPopupMenu*) FindViewById(ev, kOnlineTimePopupID);
  580.     popup2->GetMenuString(ev, str);
  581.     FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  582.     position.y += vDelta;
  583.     
  584.     // Radio buttons
  585.     CFormFrame*    frame = (CFormFrame*) GetFrame(ev);
  586.  
  587.     for (i = 0; i < kNumRadioClusters; i++)
  588.     {
  589.         button = fRadioClusters[i]->GetButtonOn(ev);
  590.         if (button) 
  591.         {
  592.             button->GetLabel(ev, str);
  593.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);
  594.             position.y += vDelta;
  595.         }
  596.     } 
  597.     
  598.     // List box
  599.     FW_CListBox* list = (FW_CListBox*)FindViewById(ev, kPlatformListBoxID);
  600.     const short maxPlaforms = 10;
  601.     short platforms[maxPlaforms];
  602.     short numSelected = list->GetSelectedItems(ev, maxPlaforms, platforms);
  603.     if (numSelected > 0)
  604.     {
  605.         for (i = 0; i < numSelected; i++)
  606.         {
  607.             list->GetStringItem(ev, platforms[i], str);
  608.             FW_CTextShape::RenderText(vc, str, position, FW_kNormalFont);            
  609.             position.y += FW_IntToFixed(16);
  610.         }
  611.     }
  612.     
  613. }
  614.  
  615. //----------------------------------------------------------------------------------------
  616. // CFormView::ResetData
  617. //----------------------------------------------------------------------------------------
  618.  
  619. void CFormView::ResetData(Environment *ev)
  620. {
  621.     // Erase the text of the 5 edit views
  622.     FW_CEditView*    edview;
  623.     for (int i = 0; i < 4; i++)
  624.     {
  625.         edview = (FW_CEditView*)FindViewById(ev, kFirstNameEdViewID+i);
  626.         edview->SetText(ev, FW_CString());
  627.     }
  628.     
  629.     CScrollEdit* scrolledit = (CScrollEdit*)FindViewById(ev, kFirstNameEdViewID+4);
  630.     scrolledit->SetText(ev, FW_CString());
  631. }
  632.  
  633. //----------------------------------------------------------------------------------------
  634. //    CFormView::Create
  635. //----------------------------------------------------------------------------------------
  636.  
  637. void* CFormView::Create(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  638. {
  639. FW_UNUSED(stream);
  640. FW_UNUSED(type);
  641.     FW_SOMEnvironment ev;
  642.     return new CFormView(ev);
  643. }
  644.  
  645. //----------------------------------------------------------------------------------------
  646. //    CFormView::Destroy
  647. //----------------------------------------------------------------------------------------
  648.  
  649. void CFormView::Destroy(void* object, FW_ClassTypeConstant type)
  650. {
  651. FW_UNUSED(type);
  652.     CFormView* self = (CFormView*) object;
  653.     delete self;
  654. }
  655.  
  656. //----------------------------------------------------------------------------------------
  657. //    CFormView::Flatten
  658. //----------------------------------------------------------------------------------------
  659.  
  660. void CFormView::Flatten(Environment* ev, FW_CWritableStream& archive) const
  661. {
  662.     FW_CSuperView::Flatten(ev, archive);
  663.     
  664.     // [LSD] to complete
  665. }
  666.  
  667. //----------------------------------------------------------------------------------------
  668. //    CFormView::InitializeFromStream
  669. //----------------------------------------------------------------------------------------
  670. // This method is required to handle the custom resource fields added to the base type
  671.  
  672. void CFormView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  673. {
  674.     // Read-in the base resource first
  675.     FW_CSuperView::InitializeFromStream(ev, stream);
  676.     
  677.     // Initialize fRadioClusters: in this version of Form the radio-clusters are not 
  678.     // declared in CFormView's resource they are in each custom RadioGroup superview. 
  679.     for (int i = 0; i < kNumRadioClusters; i++) 
  680.     {
  681.         CRadioGroup* radioGroup = (CRadioGroup*)FindViewById(ev, kSpeedRadioGroupID + i);
  682.         fRadioClusters[i] =  radioGroup->GetRadioCluster(ev); 
  683.     }    
  684. }
  685.  
  686.  
  687. //========================================================================================
  688. //    class CMouseUpBehavior
  689. //========================================================================================
  690. // Event handler class used to customize the mouse-click action in our list-box.
  691. // Having a behavior allows us to not have to subclass FW_CListBox (and also not to have
  692. // to define a new resource type in the .fr file)
  693.  
  694. FW_DEFINE_AUTO(CMouseUpBehavior)
  695.  
  696. //----------------------------------------------------------------------------------------
  697. //    CMouseUpBehavior::CMouseUpBehavior
  698. //----------------------------------------------------------------------------------------
  699.  
  700. CMouseUpBehavior::CMouseUpBehavior(Environment* ev, FW_CListBox* listBox) :
  701.     FW_MEventHandler(ev, NULL, kNoPriority),
  702.     fListBox(listBox)
  703. {
  704.     FW_END_CONSTRUCTOR
  705. }
  706.  
  707. //----------------------------------------------------------------------------------------
  708. //    CMouseUpBehavior::~CMouseUpBehavior
  709. //----------------------------------------------------------------------------------------
  710.  
  711. CMouseUpBehavior::~CMouseUpBehavior() 
  712. {
  713.     FW_START_DESTRUCTOR
  714. }
  715.  
  716. //----------------------------------------------------------------------------------------
  717. //    CMouseUpBehavior::DoMouseUp
  718. //----------------------------------------------------------------------------------------
  719. // We use the mouse up event to check if the listbox has 1 or more selected items
  720. // and enable the "Delete" button in that case.
  721. // (In that case we cannot use a mouse down event behavior because it would be executed
  722. //  before the listbox's mouse down handler, see FW_MEventHandler::DispatchMouseDown)
  723.  
  724. FW_Boolean CMouseUpBehavior::DoMouseUp(Environment* ev, const FW_CMouseEvent& theMouseEvent) 
  725. {
  726.     // Enable the "Delete" button if there are 1 or more selected items
  727.     if (fListBox->GetSelectedItem(ev) > 0)
  728.     {
  729.         FW_CSuperView* formView = fListBox->GetSuperView(ev);
  730.         FW_CButton* rmButton = (FW_CButton*) formView->FindViewById(ev, kRemoveButtonID);
  731.         FW_ASSERT(rmButton);
  732.         rmButton->Enable(ev);
  733.     }
  734.  
  735.     // let the list-box handle its mouse up event (although it doesn't matter here)
  736.     return FALSE;
  737. }
  738.